package com.project.MessageRoute.executor;

import com.project.MessageRoute.annotation.MessageRoute;
import com.project.MessageRoute.annotation.MessageRouteMethod;
import com.project.MessageRoute.model.MessageRouteBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

@Component
public class MessageRouteSetting implements ApplicationContextAware {

    private static ApplicationContext applicationValue;
    private static Map<String, List<MessageRouteBean>> serverContext = new HashMap();

    @Override
    public void setApplicationContext(ApplicationContext applicationcontext)
            throws BeansException {
        applicationValue = applicationcontext;
        String[] beanNamesForAnnotation = applicationcontext.getBeanNamesForAnnotation(MessageRoute.class);
        for(String entry : beanNamesForAnnotation){
            Class<?> type = applicationcontext.getType(entry);
            Method[] methods = type.getMethods();
            for (Method m : methods){
                if (m.isAnnotationPresent(MessageRouteMethod.class)){
                    MessageRouteMethod val = m.getAnnotation(MessageRouteMethod.class);
                    MessageRouteBean messageRouteBean = new MessageRouteBean();
                    messageRouteBean.setBean(applicationcontext.getBean(entry));
                    messageRouteBean.setMethod(m);
                    messageRouteBean.setAsync(val.async());
                    messageRouteBean.setClassName(val.className());
                    messageRouteBean.setResult(val.next());
                    messageRouteBean.setRouteMethod(val);
                    messageRouteBean.setName(nameValue(val));
                    System.out.println("==============>find name: " + messageRouteBean.getName());
                    if (!serverContext.containsKey(messageRouteBean.getName())){
                        serverContext.put(messageRouteBean.getName(), new ArrayList<>());
                    }
                    serverContext.get(messageRouteBean.getName()).add(messageRouteBean);
                }
            }
        }
    }

    private String nameValue(MessageRouteMethod md) {
        List<String> names = new ArrayList();
        names.add(md.topic());
        if (StringUtils.isNotBlank(md.tags())) {
            names.add(md.tags());
        }
        return StringUtils.join(".", names);
    }

    public static Class<?> getBeanType(String name){
        return applicationValue.getType(name);
    }

    public static List<MessageRouteBean> getBean(String name) throws InvocationTargetException, IllegalAccessException {
        if (serverContext.containsKey(name)) {
            return serverContext.get(name);
        }
        return null;
    }

    public static Map<String, List<MessageRouteBean>> getBeans(){
        return serverContext;
    }
}
